﻿using System;
using System.Collections.Generic;
using System.Text;
using Yorrick.FlickrMetadataSynchr.Properties;

namespace Yorrick.FlickrMetadataSynchr.Local
{
    /// <summary>
    /// Class that helps with parsing Flickr id metadata.
    /// </summary>
    internal static class FlickrIdHelper
    {
        /// <summary>
        /// The prefix to was used in previous versions in the metadata value to be able to recognize it as a Flickr id.
        /// </summary>
        private const string _OldFlickrIdPrefix = "FlickrId=";

        /// <summary>
        /// The prefix to use in the metadata value to be able to recognize it as a Flickr id.
        /// </summary>
        /// <remarks>0x46 is the ascii code for F and 0x49 is the ascii code for I.</remarks>
        private const string _FlickrIdPrefix = "FF4649";

        /// <summary>
        /// Length of the metadata value that contains the Flickr id.
        /// </summary>
        private const int _MetadataValueLength = 32;

        /// <summary>
        /// The character that should be used for padding in the metadata 
        /// </summary>
        private const char _PaddingCharacter = '0';

        /// <summary>
        /// Gets the value with a Flickr id to put in metadata.
        /// </summary>
        /// <param name="flickrId">The Flickr id.</param>
        /// <returns>The value to use as metadata.</returns>
        public static string GetFlickrIdForMetadata(string flickrId)
        {
            int paddingCharactersNeeded = _MetadataValueLength - flickrId.Length - _FlickrIdPrefix.Length;

            if (paddingCharactersNeeded < 0)
            {
                string errorMessage = String.Format(Messages.CannotGenerateFlickrIdMetadataValueError, flickrId);
                throw new InvalidOperationException(errorMessage);
            }

            string padding = new String(_PaddingCharacter, paddingCharactersNeeded);

            return _FlickrIdPrefix + padding + flickrId;
        }

        /// <summary>
        /// Gets the Flickr id from a metadata value or <see cref="String.Empty"/> if it doesn't contain any.
        /// </summary>
        /// <param name="metadataValue">The metadata value to parse.</param>
        /// <returns>The Flickr id from a metadata value or <see cref="String.Empty"/> if it doesn't contain any.</returns>
        public static string GetFlickrIdFromMetadata(string metadataValue)
        {
            if (ContainsFlickrId(metadataValue))
            {
                string valueWithoutPrefix = metadataValue.Remove(0, _FlickrIdPrefix.Length);

                int paddingCounter;
                for (paddingCounter = 0; paddingCounter < valueWithoutPrefix.Length; paddingCounter++)
                {
                    if (valueWithoutPrefix[paddingCounter] != _PaddingCharacter)
                    {
                        break;
                    }
                }

                if (paddingCounter < valueWithoutPrefix.Length)
                {
                    return valueWithoutPrefix.Substring(paddingCounter);
                }
                else
                {
                    return "";
                }
            }
            else if (ContainsOldFormatFlickrId(metadataValue))
            {
                return metadataValue.Remove(0, _OldFlickrIdPrefix.Length);
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// Checks if the metadata value contains a Flickr id.
        /// </summary>
        /// <param name="metadataValue">The metadata value to check.</param>
        /// <returns><c>True</c> if it contains a Flickr id, <c>false</c> otherwise.</returns>
        public static bool ContainsFlickrId(string metadataValue)
        {
            return StartsWithPrefix(metadataValue, _FlickrIdPrefix);
        }

        /// <summary>
        /// Checks if the metadata value contains a Flickr id in the old format.
        /// </summary>
        /// <param name="metadataValue">The metadata value to check.</param>
        /// <returns><c>True</c> if it contains a Flickr id, <c>false</c> otherwise.</returns>
        public static bool ContainsOldFormatFlickrId(string metadataValue)
        {
            return StartsWithPrefix(metadataValue, _OldFlickrIdPrefix);
        }

        /// <summary>
        /// Checks if the metadata value starts with a particular prefix.
        /// </summary>
        /// <param name="metadataValue">The metadata value to check.</param>
        /// <param name="prefix">The prefix that should be checked for.</param>
        /// <returns><c>True</c> if it contains a Flickr id, <c>false</c> otherwise.</returns>
        private static bool StartsWithPrefix(string metadataValue, string prefix)
        {
            if (String.IsNullOrEmpty(metadataValue))
            {
                return false;
            }
            else
            {
                return metadataValue.StartsWith(prefix);
            }
        }
    
    }
}
